
package vu.cs.heuristieken.gui;

import java.awt.Color;
import java.awt.Graphics;
import java.awt.Dimension;
import java.util.List;
import javax.swing.JComponent;
import vu.cs.heuristieken.Field;
import vu.cs.heuristieken.House;
import vu.cs.heuristieken.Column;
import vu.cs.heuristieken.Entity;
import vu.cs.heuristieken.Maison;
import vu.cs.heuristieken.Bungalow;
import vu.cs.heuristieken.Position;
import vu.cs.heuristieken.Placement;
import vu.cs.heuristieken.EengezinsWoning;

public class FieldDisplayer extends JComponent {
    private Field           field;
    private List<Placement> subFields;
    private static int CELL_WIDTH = 2;
    private static int CELL_DEPTH = 2;

    public FieldDisplayer() {
        super();
        this.field = null;
    }

    public void showField(Field field, List<Placement> subFields) {
        this.field     = field;
        this.subFields = subFields;
        this.repaint();
    }

    public void paint(Graphics graphics) {
        super.paint(graphics);
        Dimension size = this.getSize();

        if(null != field) {
            graphics.setColor(Color.WHITE);
            this._fillRect(0, 0, this.field.getWidth() * FieldDisplayer.CELL_WIDTH, this.field.getDepth() * FieldDisplayer.CELL_DEPTH, graphics);

            graphics.setColor(Color.BLACK);
            this._drawRect(0, 0, this.field.getWidth() * FieldDisplayer.CELL_WIDTH, this.field.getDepth() * FieldDisplayer.CELL_DEPTH, graphics);
            for(Placement placement : this.field.getPlacements()) {
                this._paintPlacement(placement, graphics);
            }

            for(Placement placement : this.subFields) {
                this._paintPlacement(placement, graphics);
            }
        }
    }

    private void _paintPlacement(Placement placement, Graphics graphics) {
        Entity entity = placement.getEntity();
        if(entity instanceof House) {
            this._paintHouse((House) entity, placement.getPosition(), graphics);
        }
        else if(entity instanceof Column) {
            Column column = (Column) entity;
            for(Placement p : column.getPlacements()) {
                this._paintPlacement(new Placement(p.getEntity(), new Position(placement.getPosition().getX(), p.getPosition().getY())), graphics);
            }
        }
        else if(entity instanceof Field) {
            graphics.setColor(Color.BLACK);
            this._drawRect(placement.getPosition().getX(), placement.getPosition().getY(), entity.getWidth(), entity.getDepth(), graphics);
            for(Placement p : this.field.getPlacements()) {
                this._paintPlacement(p, graphics);
            }
        }
    }

    private void _paintHouse(House house, Position position, Graphics graphics) {
        graphics.setColor(Color.GRAY);
        // this._drawRect(position.getX() - house.getVrijstand(),
        //                position.getY() - house.getVrijstand(),
        //                house.getWidth() + (2 * house.getVrijstand()),
        //                house.getDepth() + (2 * house.getVrijstand()),
        //                graphics);

        if(house instanceof Maison) {
            graphics.setColor(Color.PINK);
        }
        else if(house instanceof Bungalow) {
            graphics.setColor(Color.RED.darker());
        }
        else if(house instanceof EengezinsWoning) {
            graphics.setColor(Color.YELLOW.darker());
        }
        this._fillRect(position.getX(), position.getY(), house.getWidth(), house.getDepth(), graphics);
    }

    private void _drawRect(int beginX, int beginY, int width, int depth, Graphics graphics) {
        graphics.drawRect(beginX * FieldDisplayer.CELL_WIDTH,
                          beginY * FieldDisplayer.CELL_DEPTH,
                          width * FieldDisplayer.CELL_WIDTH,
                          depth * FieldDisplayer.CELL_DEPTH);
    }

    private void _fillRect(int beginX, int beginY, int width, int depth, Graphics graphics) {
        graphics.fillRect(beginX * FieldDisplayer.CELL_WIDTH,
                          beginY * FieldDisplayer.CELL_DEPTH,
                          width * FieldDisplayer.CELL_WIDTH,
                          depth * FieldDisplayer.CELL_DEPTH);
    }

    public Dimension getPreferredSize() {
        return this.getMinimumSize();
    }

    public Dimension getMinimumSize() {
        if(null != this.field) {
            return new Dimension(this.field.getWidth() * FieldDisplayer.CELL_WIDTH, this.field.getDepth() * FieldDisplayer.CELL_DEPTH);        
        }
        return new Dimension(0,0);
    }

    public Dimension getMaximumSize() {
        return this.getMinimumSize();
    }
}
